const express = require('express');
const http = require('http');
const socketIO = require('socket.io');
const { exec, spawn } = require('child_process');
const shell = require('shelljs');
const cors = require('cors');
const path = require('path');

const app = express();
const server = http.createServer(app);
const io = socketIO(server, {
  cors: {
    origin: '*',
    methods: ['GET', 'POST']
  }
});

// 配置中间件
app.use(cors());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());

// 存储连接的设备信息
const connectedDevices = new Map();
// 存储scrcpy进程
const scrcpyProcesses = new Map();
// 存储设备状态
const deviceStatus = new Map();

// 检查scrcpy是否已安装
function checkScrcpyInstallation() {
  return new Promise((resolve, reject) => {
    exec('scrcpy --version', (error, stdout, stderr) => {
      if (error) {
        console.error('scrcpy未安装或不在系统PATH中');
        resolve(false);
      } else {
        console.log(`scrcpy已安装: ${stdout.trim()}`);
        resolve(true);
      }
    });
  });
}

// 检查adb是否已安装
function checkAdbInstallation() {
  return new Promise((resolve, reject) => {
    exec('adb version', (error, stdout, stderr) => {
      if (error) {
        console.error('adb未安装或不在系统PATH中');
        resolve(false);
      } else {
        console.log(`adb已安装: ${stdout.split('\n')[0]}`);
        resolve(true);
      }
    });
  });
}

// 启动adb服务
function startAdbServer() {
  return new Promise((resolve, reject) => {
    exec('adb start-server', (error, stdout, stderr) => {
      if (error) {
        console.error('启动adb服务失败:', error);
        reject(error);
      } else {
        console.log('adb服务已启动');
        resolve();
      }
    });
  });
}

// 获取已连接的安卓设备
app.get('/api/devices', async (req, res) => {
  try {
    // 先启动adb服务
    await startAdbServer();
    
    exec('adb devices', (error, stdout, stderr) => {
      if (error) {
        console.error('获取设备列表失败:', error);
        return res.status(500).json({ error: '获取设备列表失败' });
      }
      
      // 解析adb devices输出
      const lines = stdout.trim().split('\n');
      // 跳过第一行 "List of devices attached"
      const devices = lines.slice(1).map(line => {
        const [id, status] = line.trim().split('\t');
        return { 
          id, 
          status,
          isStreaming: scrcpyProcesses.has(id),
          isConnected: deviceStatus.get(id) || false
        };
      }).filter(device => device.id && device.status);
      
      res.json({ devices });
    });
  } catch (error) {
    console.error('获取设备列表失败:', error);
    res.status(500).json({ error: '获取设备列表失败', details: error.message });
  }
});

// 获取设备信息
app.get('/api/device/:deviceId/info', (req, res) => {
  const { deviceId } = req.params;
  
  exec(`adb -s ${deviceId} shell getprop`, (error, stdout, stderr) => {
    if (error) {
      return res.status(500).json({ error: '获取设备信息失败' });
    }
    
    const props = {};
    stdout.split('\n').forEach(line => {
      const match = line.match(/\[([^\]]+)\]:\s*\[([^\]]*)\]/);
      if (match) {
        props[match[1]] = match[2];
      }
    });
    
    res.json({
      deviceId,
      manufacturer: props['ro.product.manufacturer'] || 'Unknown',
      model: props['ro.product.model'] || 'Unknown',
      androidVersion: props['ro.build.version.release'] || 'Unknown',
      sdkVersion: props['ro.build.version.sdk'] || 'Unknown',
      resolution: props['ro.sf.lcd_density'] || 'Unknown'
    });
  });
});

// 启动投屏
app.post('/api/start-stream', (req, res) => {
  const { deviceId } = req.body;
  
  if (!deviceId) {
    return res.status(400).json({ error: '设备ID不能为空' });
  }
  
  // 检查是否已经有该设备的投屏进程
  if (scrcpyProcesses.has(deviceId)) {
    return res.status(400).json({ error: '该设备的投屏已经在运行' });
  }
  
  try {
    console.log(`准备启动scrcpy进程，设备ID: ${deviceId}`);
    
    // 使用scrcpy输出视频流到stdout，供浏览器直接播放
    const scrcpy = spawn('scrcpy', [
      '--serial', deviceId,
      '--no-playback',          // 不显示窗口
      '--video-bit-rate', '2M', // 提高比特率
      '--max-size', '1280',     // 提高分辨率
      '--max-fps', '30',        // 提高帧率
      '--no-audio',             // 禁用音频
      '--show-touches',         // 显示触摸操作
      '--stay-awake',           // 保持设备唤醒
      '--video-codec', 'h264'   // 使用H.264编码
    ]);
    
    scrcpyProcesses.set(deviceId, scrcpy);
    deviceStatus.set(deviceId, true);
    
    // 处理视频流数据
    scrcpy.stdout.on('data', (data) => {
      io.emit(`stream:${deviceId}`, data);
    });
    
    // 处理错误输出
    scrcpy.stderr.on('data', (data) => {
      const message = data.toString().trim();
      console.log(`scrcpy输出 (${deviceId}):`, message);
      
      if (message.includes('ERROR') || message.includes('error') || 
          message.includes('failed') || message.includes('Failed')) {
        console.error(`scrcpy错误 (${deviceId}):`, message);
        io.emit(`error:${deviceId}`, message);
      } else {
        io.emit(`info:${deviceId}`, message);
      }
    });
    
    scrcpy.on('close', (code) => {
      console.log(`scrcpy进程关闭 (${deviceId}), 退出码: ${code}`);
      scrcpyProcesses.delete(deviceId);
      deviceStatus.set(deviceId, false);
      io.emit(`disconnect:${deviceId}`);
    });
    
    scrcpy.on('error', (error) => {
      console.error(`scrcpy进程错误 (${deviceId}):`, error);
      scrcpyProcesses.delete(deviceId);
      deviceStatus.set(deviceId, false);
      io.emit(`error:${deviceId}`, error.message);
    });
    
    res.json({ success: true, message: '投屏已启动' });
  } catch (error) {
    console.error('启动投屏失败:', error);
    res.status(500).json({ error: '启动投屏失败', details: error.message });
  }
});

// 停止投屏
app.post('/api/stop-stream', (req, res) => {
  const { deviceId } = req.body;
  
  if (!deviceId || !scrcpyProcesses.has(deviceId)) {
    return res.status(400).json({ error: '没有找到该设备的投屏进程' });
  }
  
  const scrcpy = scrcpyProcesses.get(deviceId);
  scrcpy.kill('SIGTERM');
  
  // 如果进程没有立即退出，强制终止
  setTimeout(() => {
    if (scrcpy.exitCode === null) {
      scrcpy.kill('SIGKILL');
    }
  }, 2000);
  
  scrcpyProcesses.delete(deviceId);
  deviceStatus.set(deviceId, false);
  
  res.json({ success: true, message: '投屏已停止' });
});

// 执行adb命令控制设备
app.post('/api/control', (req, res) => {
  const { deviceId, command, params = [] } = req.body;
  
  if (!deviceId || !command) {
    return res.status(400).json({ error: '设备ID和命令不能为空' });
  }
  
  let adbCommand = `adb -s ${deviceId} ${command}`;
  if (params.length > 0) {
    adbCommand += ' ' + params.join(' ');
  }
  
  exec(adbCommand, (error, stdout, stderr) => {
    if (error) {
      console.error(`执行命令失败: ${adbCommand}`, error);
      return res.status(500).json({ 
        error: '执行命令失败', 
        command: adbCommand, 
        stderr: stderr.toString()
      });
    }
    
    res.json({ 
      success: true, 
      command: adbCommand, 
      stdout: stdout.toString()
    });
  });
});

// 截图功能
app.post('/api/screenshot', (req, res) => {
  const { deviceId } = req.body;
  
  if (!deviceId) {
    return res.status(400).json({ error: '设备ID不能为空' });
  }
  
  const timestamp = Date.now();
  const filename = `screenshot_${deviceId}_${timestamp}.png`;
  const filepath = path.join(__dirname, 'public', 'screenshots', filename);
  
  // 确保screenshots目录存在
  shell.mkdir('-p', path.join(__dirname, 'public', 'screenshots'));
  
  exec(`adb -s ${deviceId} shell screencap -p /sdcard/screenshot.png && adb -s ${deviceId} pull /sdcard/screenshot.png "${filepath}"`, (error, stdout, stderr) => {
    if (error) {
      console.error('截图失败:', error);
      return res.status(500).json({ error: '截图失败' });
    }
    
    res.json({ 
      success: true, 
      filename: filename,
      url: `/screenshots/${filename}`
    });
  });
});

// Socket.io 连接处理
io.on('connection', (socket) => {
  console.log('客户端已连接:', socket.id);
  
  // 监听设备连接事件
  socket.on('device:connect', (deviceId) => {
    connectedDevices.set(socket.id, deviceId);
    console.log(`设备已连接到客户端: ${deviceId} -> ${socket.id}`);
  });
  
  // 监听用户输入事件（如点击、滑动等）
  socket.on('user:input', (data) => {
    const { deviceId, type, x, y, action, duration } = data;
    
    if (!deviceId || !type) {
      console.error('无效的用户输入数据');
      return;
    }
    
    let adbCommand = '';
    
    // 根据输入类型生成adb命令
    switch (type) {
      case 'tap':
        adbCommand = `adb -s ${deviceId} shell input tap ${x} ${y}`;
        break;
      case 'swipe':
        const { startX, startY, endX, endY } = x;
        adbCommand = `adb -s ${deviceId} shell input swipe ${startX} ${startY} ${endX} ${endY} ${duration || 100}`;
        break;
      case 'keyevent':
        adbCommand = `adb -s ${deviceId} shell input keyevent ${action}`;
        break;
      case 'text':
        adbCommand = `adb -s ${deviceId} shell input text "${x}"`;
        break;
      case 'longpress':
        adbCommand = `adb -s ${deviceId} shell input swipe ${x} ${y} ${x} ${y} 1000`;
        break;
    }
    
    if (adbCommand) {
      exec(adbCommand, (error, stdout, stderr) => {
        if (error) {
          console.error(`执行输入命令失败: ${adbCommand}`, error);
          socket.emit('input:error', { deviceId, error: error.message });
        } else {
          socket.emit('input:success', { deviceId, command: adbCommand });
        }
      });
    }
  });
  
  // 断开连接处理
  socket.on('disconnect', () => {
    const deviceId = connectedDevices.get(socket.id);
    if (deviceId) {
      console.log(`客户端断开连接: ${socket.id} (设备: ${deviceId})`);
      connectedDevices.delete(socket.id);
      
      // 检查是否还有其他客户端连接到该设备
      let hasOtherConnections = false;
      for (const id of connectedDevices.values()) {
        if (id === deviceId) {
          hasOtherConnections = true;
          break;
        }
      }
      
      // 如果没有其他客户端连接到该设备，停止投屏进程
      if (!hasOtherConnections && scrcpyProcesses.has(deviceId)) {
        console.log(`停止设备 ${deviceId} 的投屏进程，因为没有客户端连接`);
        const scrcpy = scrcpyProcesses.get(deviceId);
        scrcpy.kill('SIGTERM');
        scrcpyProcesses.delete(deviceId);
        deviceStatus.set(deviceId, false);
      }
    }
  });
});

// 启动服务器
const PORT = process.env.PORT || 3000;

async function startServer() {
  try {
    const [scrcpyInstalled, adbInstalled] = await Promise.all([
      checkScrcpyInstallation(),
      checkAdbInstallation()
    ]);
    
    if (!scrcpyInstalled) {
      console.warn('警告: scrcpy未安装。请先安装scrcpy以使用投屏功能。');
    }
    
    if (!adbInstalled) {
      console.warn('警告: adb未安装。请先安装Android SDK Platform Tools以使用设备控制功能。');
    }
    
    // 如果ADB已安装，启动ADB服务
    if (adbInstalled) {
      try {
        await startAdbServer();
        console.log('ADB服务已启动');
      } catch (error) {
        console.error('启动ADB服务失败:', error);
      }
    }
    
    server.listen(PORT, () => {
      console.log(`服务器运行在 http://localhost:${PORT}`);
      console.log(`scrcpy状态: ${scrcpyInstalled ? '已安装' : '未安装'}`);
      console.log(`adb状态: ${adbInstalled ? '已安装' : '未安装'}`);
    });
  } catch (error) {
    console.error('启动服务器失败:', error);
    process.exit(1);
  }
}

startServer();